package jp.co.kayo.gae.takidashibot.controller.takidasibot;

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import jp.co.kayo.gae.takidashibot.controller.JsonController;
import jp.co.kayo.gae.takidashibot.meta.TakidasiMeta;
import jp.co.kayo.gae.takidashibot.model.Takidasi;
import jp.co.kayo.gae.takidashibot.utils.Coords;
import jp.co.kayo.gae.takidashibot.utils.TakidasiPair;
import jp.co.kayo.gae.takidashibot.utils.Utils;

import org.slim3.datastore.Datastore;
import org.slim3.util.RequestMap;

import com.google.appengine.repackaged.com.google.common.collect.Maps;

public class Search2Controller extends JsonController {
    private SimpleDateFormat _sdf;
    
    
    public SimpleDateFormat getSDF(){
        if(_sdf == null){
            _sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm");
            TimeZone tz = TimeZone.getTimeZone("Asia/Tokyo");
            _sdf.setTimeZone(tz);
        }
        return _sdf;
    }    
    
    @Override
    protected Map<String, Object> handle() throws Exception {
        RequestMap input = new RequestMap(request);
        
        double lat = Utils.getDouble(input.get("lat"));
        double lng = Utils.getDouble(input.get("lng"));
        double dist = Utils.getDouble(input.get("m"));
        int limit = Utils.getInt(input.get("n"));
        String type = (String)input.get("t");
        String callback = (String)input.get("callback");
        String keyword1 = (String)input.get("str1");
        String keyword2 = (String)input.get("str2");
        
        if("jsonp".equals(type)){
            if(callback==null || callback.length()==0 || !callback.matches("/^[a-zA-Z]+$/")){
                setCallback("search");
            }
            else{
                setCallback(callback);
            }
        }
        
        //デフォルトを3000にする
        if(dist<=0){
            dist = 3000;
        }
        
        TakidasiMeta tm = TakidasiMeta.get();
        List<Takidasi> points = Datastore.query(tm).asList();

        boolean checkstr1 = keyword1!=null && keyword1.length()>0;
        boolean checkstr2 = keyword2!=null && keyword2.length()>0;
        if (points != null && points.size() > 1) {
            List<TakidasiPair> founds = new ArrayList<TakidasiPair>();
            for(Takidasi t : points){
                double m = Coords.calcDistHubeny(t.getLat(), t.getLng(), lat, lng);
                //30km以下
                if(m < dist){
                    if(checkstr1){
                        if(t.getDescription().contains(keyword1)
                         ||t.getName().contains(keyword1)
                         ||t.getAddr().contains(keyword1)){
                            if(checkstr2){
                                if(t.getDescription().contains(keyword2)
                                        ||t.getName().contains(keyword2)
                                        ||t.getAddr().contains(keyword2)){
                                    founds.add(new TakidasiPair(m, t));
                                }
                            }
                            else{
                                founds.add(new TakidasiPair(m, t));                                
                            }
                        }
                    }
                    else{
                        founds.add(new TakidasiPair(m, t));
                    }
                }
             }
             if(founds.size()>0){
                 Collections.sort(founds);
                 List<Map<String, Object>> array = new ArrayList<Map<String, Object>>();
                 int count = 0;
                 for(TakidasiPair t : founds){
                     if(limit>0 && (count++)>=limit){
                         break;
                     }
                     double km = t.dist;
                     
                     StringBuilder urlstr = new StringBuilder();
                     urlstr.append("http://maps.google.com/maps?q=")
                     .append(t.takidasi.getLat()).append(",")
                     .append(t.takidasi.getLng()).append("+(")
                     .append(URLEncoder.encode(t.takidasi.getName(), "UTF-8")).append(")");
                     
                     StringBuilder body = new StringBuilder();
                     body.append(Utils.fixString(t.takidasi.getDescription()));
                     body.append(" ");
                     
                     Date date = new Date(t.takidasi.getCreatedAt());
                     body.append("(").append(getSDF().format(date)).append(" 登録)");
                     
                     Map<String, Object> map = Maps.newHashMap();
                     map.put("distance", km);
                     map.put("latitude", t.takidasi.getLat());
                     map.put("longitude", t.takidasi.getLng());
                     map.put("title", t.takidasi.getName());
                     map.put("date", new Date(t.takidasi.getCreatedAt()));
                     map.put("description", t.takidasi.getDescription());
                     map.put("id", t.takidasi.getId());
                     map.put("body", body.toString());
                     map.put("map", urlstr.toString());
                     array.add(map);
                 }
                 
                 Map<String, Object> result = Maps.newHashMap();
                 result.put(TYPE_ARRAY, array);
                 return result;
             }
        }
        
        return Maps.newHashMap();
    }
}
